/*
 * TBX: ToolBoX of Simgrid : some convenient tools (FIFO lists, hash
 * tables, graphs,...)  Copyright (C) 2002 "the MSG Team" (see AUTHORS
 * file).
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2, or (at
 * your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
 * USA.
 */

#ifndef TBX_MACROS_H
#define TBX_MACROS_H

#include "simgrid_config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>


/******************************************/
/* MAX/MINmacros                          */
/******************************************/
#ifndef MAX
#define MAX(x,y) ((x)>(y)?(x):(y))
#endif
#ifndef MIN
#define MIN(x,y) ((x)<(y)?(x):(y))
#endif
#ifndef EXTENDEDMIN
#define EXTENDEDMIN(x,y) (((y) == -1.0) ? (x) : (((x)==-1) ? (y)  : (((x)<(y)) ? (x) : (y))))
#endif
#ifndef ABS
#define ABS(x) ((x)>0?(x):(-(x)))
#endif


/******************************************/
/* Failure, Assert, warning, ...          */
/******************************************/

#if HAVE_GCC == 1
#define __ATTRIBUTE_UNUSED__ __attribute__ ((unused))
#define __INLINE__ __inline__
#if HAVE_GCC_SUPORT_BUILTINS == 1
#define unlikely(x)  __builtin_expect((x),0)
#else
#define unlikely(x)  (x)
#endif
#define ASSERT(test, ...) ((unlikely(test))?:(FAILURE(__VA_ARGS__)))
/* #define CHECK(test, ...)  ((unlikely(test))?:(WARNING(__VA_ARGS__),return MSG_WARNING)) */

#define FAILURE(format, ...) (fprintf(stderr, "[%s , %s : %d] ", __FILE__, __FUNCTION__, __LINE__),\
                              fprintf(stderr, format, ## __VA_ARGS__),\
                              fprintf(stderr, "\n"),\
                              abort())
#define WARNING(format, ...) (fprintf(stderr, "[%s , %s : %d] ", __FILE__, __FUNCTION__, __LINE__),\
                              fprintf(stderr, format, ## __VA_ARGS__), \
                              fprintf(stderr, "\n"))
/******************************************/
/* Calloc, free, strdup, ...              */
/******************************************/
#define __CALLOC_OP(n, s)  calloc((n), (s))
#define __REALLOC_OP(n, s)  realloc((n), (s))
#define __FREE_OP(s)  free((s))
#define __STRDUP_OP(s)  strdup((s))
#define CALLOC(n, s)  ((__CALLOC_OP  ((n)?:(FAILURE("attempt to alloc 0 bytes"), 0), (s)?:(FAILURE("attempt to alloc 0 bytes"), 0)))?:(FAILURE("memory allocation error"), NULL))
/* #define REALLOC(p, s) ((__REALLOC_OP ((p), (s)?:(FAILURE("attempt to alloc 0 bytes"), 0)))?:(FAILURE("memory reallocation error"), NULL)) */
#define REALLOC(p, s) (__REALLOC_OP ((p), (s)))
#define FREE(s)       (__FREE_OP ((s)?:(FAILURE("attempt to free a NULL area"), NULL)),s=NULL)
#define STRDUP(s)  ((s)?((__STRDUP_OP ((s)))?:(FAILURE("memory allocation error"),NULL)):(NULL))

#else /* no GNUCC */
#define __ATTRIBUTE_UNUSED__
#define __INLINE__   
void ASSERT(int test, const char *fmt, ...) ;
int FAILURE(const char *fmt, ...) ;
int WARNING(const char *fmt, ...) ;
#define CALLOC(n, s)  calloc(n,s)
#define REALLOC(p, s) realloc(p,s)
#define FREE(s)       (free(s),s=NULL)
#define STRDUP(s)     strdup(s)
#endif /* GNUCC */


#define VOIRS(expr) WARNING("  {" #expr " = %s }", expr)
#define VOIRP(expr) WARNING("  {" #expr " = %p }", expr)
#define VOIRD(expr) WARNING("  {" #expr " = %d }", expr)
#define VOIRF(expr) WARNING("  {" #expr " = %Lf }", expr)
#define VOIRG(expr) WARNING("  {" #expr " = %Lg }", expr)


#endif
